﻿package com.hc.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;

import android.annotation.SuppressLint;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.DhcpInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.widget.Toast;

/**
 * wifi管理工具
 * 
 * @ClassName: Wifimanager
 * @Description: TODO
 * @author chenzhili
 * @date 2013-3-29 下午4:14:41
 * 
 */
public class Wifimanager {

	// 程序环境
	private Context context;
	// wifi管理器
	private static WifiManager manager;
	private int state;
	// wifi配置
	private static WifiConfiguration wifiConfiguration;
	private List<WifiConfiguration> list;
	private List<ScanResult> listScanResults;
	private WifiLock mWifiLock;

	// private ConnectivityManager connectivityManager;

	public Wifimanager(Context context) {
		this.context = context;
		// connectivityManager = (ConnectivityManager) context
		// .getSystemService(Context.CONNECTIVITY_SERVICE);
		manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
	}

	public boolean openWifi() {

		if (!manager.isWifiEnabled()) {
			return manager.setWifiEnabled(true);
		} else {
			return false;
		}
		// show("正在打开Wifi...", Toast.LENGTH_SHORT);
	}

	public DhcpInfo getDhcpInfo() {
		return manager.getDhcpInfo();
	}

	public void closeWifi() {
		state = manager.getWifiState();
		if (manager.isWifiEnabled()) {
			manager.setWifiEnabled(false);
		}
		show("正在关闭Wifi...", Toast.LENGTH_SHORT);
	}

	// 搜索可连接wifi
	public List<ScanResult> getAllWifiInfo() {
		return listScanResults;
	}

	public WifiManager getWifManager() {
		return manager;
	}

	// public HashMap<String,String> getAllWifiInfo() {
	// listScanResults = manager.getScanResults();
	//
	// }
	public void scanWifi() {
		manager.startScan();
		listScanResults = manager.getScanResults();
		list = manager.getConfiguredNetworks();
	}

	public void setScanResult(List<ScanResult> list) {
		this.listScanResults = list;
	}

	/**
	 * 获取已连接的wifi信息 SSID:ap名称 frequency：ap频段 capabilities:ap性能 level ：ap的dBm值
	 */
	public HashMap<String, String> getConnectionInfo() {
		// 取得WifiInfo对象
		WifiInfo wifiInfo = manager.getConnectionInfo();
		HashMap<String, String> info = new HashMap<String, String>();
		info.put("ssid", wifiInfo.getSSID());
		info.put("bssid", wifiInfo.getBSSID());
		info.put("mac", wifiInfo.getMacAddress());
		info.put("ip", parseIpFromInt(wifiInfo.getIpAddress()));
		info.put("netId", wifiInfo.getNetworkId() + "");
		info.put("rssi", wifiInfo.getRssi() + "");
		return info;
	}

	// 添加新ap
	public int addNetWork(WifiConfiguration configuration) {
		return manager.addNetwork(configuration);
	}

	// 连接一个已有的ap
	public boolean connectNetWork(int netId) {
		return manager.enableNetwork(netId, true);
	}

	// 锁定WifiLock
	public void AcquireWifiLock() {
		mWifiLock.acquire();
	}

	// 创建并锁定
	public void createAndLock() {
		if (mWifiLock == null) {
			CreatWifiLock();
		}
		AcquireWifiLock();

	}

	// 解锁WifiLock
	public void ReleaseWifiLock() {
		// 判断时候锁定
		if (mWifiLock.isHeld()) {
			mWifiLock.acquire();
		}
	}

	// 创建一个WifiLock
	public void CreatWifiLock() {
		mWifiLock = manager.createWifiLock("connect");
	}

	// 可能不能连接
	public boolean connectNetWork(WifiConfiguration configuration) {
		return manager.enableNetwork(configuration.networkId, true);
	}

	// 删除已保存的连接
	public void removeNetWork(String ssid) {
		list = manager.getConfiguredNetworks();
		for (WifiConfiguration wc : list) {
			if (wc.SSID.equals("\"" + ssid + "\"")) {
				manager.removeNetwork(wc.networkId);
			}
		}
	}

	// 创建一个连接，并连接
	@Deprecated
	public void createWifiAndConnection(String ssid, String password, int Type) {
		WifiConfiguration config = new WifiConfiguration();
		removeNetWork(ssid);
		config.allowedAuthAlgorithms.clear();
		config.allowedGroupCiphers.clear();
		config.allowedKeyManagement.clear();
		config.allowedPairwiseCiphers.clear();
		config.allowedProtocols.clear();
		config.SSID = "\"" + ssid + "\"";

		// if (Type == WifiConfiguration.KeyMgmt.NONE) {//access.SECURITY_NONE
		// config.wepKeys[0] = "";
		// config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
		// config.wepTxKeyIndex = 0;
		// }
		if (Type == WifiConfiguration.KeyMgmt.NONE) { // AccessPoint.SECURITY_WEP
			config.hiddenSSID = true;
			config.preSharedKey = "\"" + password + "\"";
			config.allowedAuthAlgorithms
					.set(WifiConfiguration.AuthAlgorithm.SHARED);
			config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
			config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
			config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
			config.allowedGroupCiphers
					.set(WifiConfiguration.GroupCipher.WEP104);
			config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
			config.wepTxKeyIndex = 0;
		}
		if (Type == WifiConfiguration.KeyMgmt.WPA_PSK) { // AccessPoint.SECURITY_PSK
			config.preSharedKey = "\"" + password + "\"";
			config.hiddenSSID = true;
			config.status = WifiConfiguration.Status.ENABLED;
			config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
			config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
			config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
			config.allowedPairwiseCiphers
					.set(WifiConfiguration.PairwiseCipher.TKIP);
			config.allowedPairwiseCiphers
					.set(WifiConfiguration.PairwiseCipher.CCMP);
			config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
		}
		int res = manager.addNetwork(config);
		manager.enableNetwork(res, true);
	}

	public ScanResult getConfigurationByIndex(int index) {
		if (index < listScanResults.size()) {
			return listScanResults.get(index);
		} else {
			return null;
		}
	}

	/**
	 * 静态连接wifi
	 * 
	 * @Title: staticConnectWifi
	 * @Description: TODO
	 * @param ip
	 *            ip地址
	 * @param gateWay
	 *            网关
	 * @param Netmask
	 *            掩码
	 * @param DNS1
	 *            dns地址
	 * @param DNS2
	 *            dns地址
	 * @throws
	 */
	public void staticConnectWifi(String ip, String gateWay, String Netmask,
			String DNS) throws Exception {
		setIpAssignment("STATIC", wifiConfiguration); // or "DHCP" for
		// dynamic setting
		setIpAddress(InetAddress.getByAddress(transferIPtoByte(ip)), 24, wifiConfiguration);
		setGateway(InetAddress.getByAddress(transferIPtoByte(gateWay)), wifiConfiguration);
		setDNS(InetAddress.getByAddress(transferIPtoByte(DNS)), wifiConfiguration);
		manager.updateNetwork(wifiConfiguration); // apply the setting
	}

	public static void setIpAssignment(String assign, WifiConfiguration wifiConf)
			throws Exception {
		Field f = wifiConf.getClass().getField("ipAssignment");
		f.set(wifiConf, Enum.valueOf((Class<Enum>) f.getType(), assign));
	}

	public static void setIpAddress(InetAddress addr, int prefixLength,
			WifiConfiguration wifiConf) throws Exception {
		Object linkProperties = getField(wifiConf, "linkProperties");
		if (linkProperties == null)
			return;
		Class laClass = Class.forName("android.net.LinkAddress");
		Constructor laConstructor = laClass.getConstructor(new Class[] {
				InetAddress.class, int.class });
		Object linkAddress = laConstructor.newInstance(addr, prefixLength);

		ArrayList mLinkAddresses = (ArrayList) getDeclaredField(linkProperties,
				"mLinkAddresses");
		mLinkAddresses.clear();
		mLinkAddresses.add(linkAddress);
	}

	public static void setGateway(InetAddress gateway,
			WifiConfiguration wifiConf) throws SecurityException,
			IllegalArgumentException, NoSuchFieldException,
			IllegalAccessException, ClassNotFoundException,
			NoSuchMethodException, InstantiationException,
			InvocationTargetException {
		Object linkProperties = getField(wifiConf, "linkProperties");
		if (linkProperties == null)
			return;
		Class routeInfoClass = Class.forName("android.net.RouteInfo");
		Constructor routeInfoConstructor = routeInfoClass
				.getConstructor(new Class[] { InetAddress.class });
		Object routeInfo = routeInfoConstructor.newInstance(gateway);

		ArrayList mRoutes = (ArrayList) getDeclaredField(linkProperties,
				"mRoutes");
		mRoutes.clear();
		mRoutes.add(routeInfo);
	}

	public static void setDNS(InetAddress dns, WifiConfiguration wifiConf)
			throws SecurityException, IllegalArgumentException,
			NoSuchFieldException, IllegalAccessException {
		Object linkProperties = getField(wifiConf, "linkProperties");
		if (linkProperties == null)
			return;
		// wificonfiguretion$
		ArrayList<InetAddress> mDnses = (ArrayList<InetAddress>) getDeclaredField(
				linkProperties, "mDnses");
		mDnses.clear(); // or add a new dns address , here I just want to
						// replace DNS1
		mDnses.add(dns);
	}

	public static Object getField(Object obj, String name)
			throws SecurityException, NoSuchFieldException,
			IllegalArgumentException, IllegalAccessException {
		Field f = obj.getClass().getField(name);
		Object out = f.get(obj);
		return out;
	}

	public static Object getDeclaredField(Object obj, String name)
			throws SecurityException, NoSuchFieldException,
			IllegalArgumentException, IllegalAccessException {
		Field f = obj.getClass().getDeclaredField(name);
		f.setAccessible(true);
		Object out = f.get(obj);
		return out;
	}

	public static void setEnumField(Object obj, String value, String name)
			throws SecurityException, NoSuchFieldException,
			IllegalArgumentException, IllegalAccessException {
		Field f = obj.getClass().getField(name);
		f.set(obj, Enum.valueOf((Class<Enum>) f.getType(), value));
	 
	}

	public WifiConfiguration getWIConfigurationbySSID(String SSID) {
		list = manager.getConfiguredNetworks();
		if (list == null || list.size() < 0) {
			return null;
		}
		for (int i = 0; i < list.size(); i++) {
			wifiConfiguration = list.get(i);
			if (wifiConfiguration.SSID.equals(SSID)) {
				System.out.println("equals...");
				return wifiConfiguration;
			}
		}
		return null;
	}
   
	public byte[] transferIPtoByte(String ip) {
		StringTokenizer tokenizer = new StringTokenizer(ip, ".");
		int i = 0;
		byte[] ips = new byte[4];
		while (tokenizer.hasMoreTokens()) {
			ips[i] = (byte)(Integer.parseInt(tokenizer.nextToken())&0xFF);
			i++;
		}
		return ips;
	}
	
	
	

	// D-Link_DIR-600Meeee
	public ScanResult getScanResultBySSID(String ssid) {
		ScanResult result = null;
		if (listScanResults.size() > 0 && listScanResults != null) {
			for (int i = 0; i < listScanResults.size(); i++) {
				result = listScanResults.get(i);
				if (result.SSID.equals(ssid)) {
					break;
				}
			}
		}
		return result;
	}

	public String getcapabilities(ScanResult scanRet) {
		return scanRet.capabilities;
	}

	public boolean connectionWifiByScanReulst(ScanResult scanRet,
			String password) {
		if (scanRet == null) {
			show("没有可用连接...", 0);
			return false;
		}
		WifiConfiguration config = createWifiConfiguration(scanRet, password);
		int temp = manager.addNetwork(config);
		return manager.enableNetwork(temp, true);
	}

	public WifiConfiguration createWifiConfiguration(ScanResult scanRet,
			String password) {
		WifiConfiguration config = new WifiConfiguration();
		config.SSID = "\"" + scanRet.SSID + "\""; // 配置wifi的SSID，即该热点的名称，如：TP-link_xxx
		config.hiddenSSID = true;
		config.allowedAuthAlgorithms.clear();
		config.allowedGroupCiphers.clear();
		config.allowedKeyManagement.clear();
		config.allowedPairwiseCiphers.clear();
		config.allowedProtocols.clear();
		if (scanRet.capabilities.contains("WPA")
				&& !scanRet.capabilities.contains("WPA2")) {
			config.preSharedKey = "\"" + password + "\""; // 该热点的密码
			config.allowedAuthAlgorithms
					.set(WifiConfiguration.AuthAlgorithm.OPEN);
			config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
			config.status = WifiConfiguration.Status.ENABLED;
		}
		if (scanRet.capabilities.contains("WPA2")) {
			config.preSharedKey = "\"" + password + "\""; // 该热点的密码
			config.allowedAuthAlgorithms
					.set(WifiConfiguration.AuthAlgorithm.OPEN);
			config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
			config.status = WifiConfiguration.Status.ENABLED;
		}
		if (scanRet.capabilities.contains("PSK")) {
			config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
		}
		if (scanRet.capabilities.contains("TKIP")) {
			config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
			config.allowedPairwiseCiphers
					.set(WifiConfiguration.PairwiseCipher.TKIP);
		}
		if (scanRet.capabilities.contains("CCMP")) {
			config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
			config.allowedPairwiseCiphers
					.set(WifiConfiguration.PairwiseCipher.CCMP);
		}
		if (scanRet.capabilities.contains("EAP")) {
			config.allowedAuthAlgorithms
					.set(WifiConfiguration.AuthAlgorithm.LEAP);
			config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
		}
		if (scanRet.capabilities.contains("WEP")) {
			config.allowedAuthAlgorithms
					.set(WifiConfiguration.AuthAlgorithm.SHARED);
			config.wepKeys[0] = "\"" + password + "\"";
			config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
			config.allowedGroupCiphers
					.set(WifiConfiguration.GroupCipher.WEP104);
			config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
			config.wepTxKeyIndex = 0;
		}
		if (scanRet.capabilities.equals("")) {
			config.wepKeys[0] = "";
			config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
			config.wepTxKeyIndex = 0;
		}
//		if (scanRet.capabilities.equals("[ESS]")) {
//			// config.wepKeys[0] = "";
//			// config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
//			// config.wepTxKeyIndex = 0;
//			config = getWIConfigurationbySSID(scanRet.SSID);
//		}
		removeNetWork(scanRet.SSID);
		int temp = manager.addNetwork(config);
		config.networkId = temp;
		wifiConfiguration = config;
		return config;
	}

	// 连接已有的
	public void connectionWifi(String ssid, String password, String capabilities) {
		if (capabilities == null || capabilities.equals("")) {
			show("没有可用连接...", 0);
			return;
		}
		WifiConfiguration config = new WifiConfiguration();
		config.SSID = "\"" + ssid + "\""; // 配置wifi的SSID，即该热点的名称，如：TP-link_xxx
		config.preSharedKey = "\"" + password + "\""; // 该热点的密码
		config.hiddenSSID = true;
		config.allowedAuthAlgorithms.clear();
		config.allowedGroupCiphers.clear();
		config.allowedKeyManagement.clear();
		config.allowedPairwiseCiphers.clear();
		config.allowedProtocols.clear();
		if (capabilities.contains("WPA") && !capabilities.contains("WPA2")) {
			config.allowedAuthAlgorithms
					.set(WifiConfiguration.AuthAlgorithm.OPEN);
			config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
			config.status = WifiConfiguration.Status.ENABLED;
		}
		if (capabilities.contains("WPA2")) {
			config.allowedAuthAlgorithms
					.set(WifiConfiguration.AuthAlgorithm.OPEN);
			config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
			config.status = WifiConfiguration.Status.ENABLED;
		}
		if (capabilities.contains("PSK")) {
			config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
		}
		if (capabilities.contains("TKIP")) {
			config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
			config.allowedPairwiseCiphers
					.set(WifiConfiguration.PairwiseCipher.TKIP);
		}
		if (capabilities.contains("CCMP")) {
			config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
			config.allowedPairwiseCiphers
					.set(WifiConfiguration.PairwiseCipher.CCMP);
		}
		if (capabilities.contains("EAP")) {
			config.allowedAuthAlgorithms
					.set(WifiConfiguration.AuthAlgorithm.LEAP);
			config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
		}
		if (capabilities.contains("WEP")) {
			config.allowedAuthAlgorithms
					.set(WifiConfiguration.AuthAlgorithm.SHARED);
			config.wepKeys[0] = "\"" + password + "\"";
			config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
			config.allowedGroupCiphers
					.set(WifiConfiguration.GroupCipher.WEP104);
			config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
			config.wepTxKeyIndex = 0;
		}
		if (capabilities.equals("")) {
			config.wepKeys[0] = "";
			config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
			config.wepTxKeyIndex = 0;
		}

		removeNetWork(ssid);
		int temp = manager.addNetwork(config);
		manager.enableNetwork(temp, true);
	}

	public WifiInfo getConnectWifiInfo() {
		return manager.getConnectionInfo();
	}

	// 断开连接
	public void disConnect() {
		manager.disconnect();
	}

	public void reconnect() {
		manager.reconnect();
	}

	public int getWifiState() {
		return manager.getWifiState();
	}

	@SuppressLint("DefaultLocale")
	public String parseIpFromInt(int ipAddress) {
		return String.format("%d.%d.%d.%d", (ipAddress & 0xff),
				(ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff),
				(ipAddress >> 24 & 0xff));
	}

	private void show(String content, int duration) {
		Toast.makeText(context, content, duration).show();
	}

	public List<ScanResult> searchHeightFrequencyWifi(
			List<ScanResult> listScanResults) {
		List<ScanResult> hList = new ArrayList<ScanResult>();
		// List<ScanResult> temp = getAllWifiInfo();
		if (listScanResults != null && listScanResults.size() > 0) {
			for (ScanResult rs : listScanResults) {
				if (rs.frequency > 2484) {
					hList.add(rs);
				}
			}
		}
		return hList;
	}

	public List<ScanResult> searchLowFrequencyWifi(
			List<ScanResult> listScanResults) {
		List<ScanResult> hList = new ArrayList<ScanResult>();
		// List<ScanResult> temp = getAllWifiInfo();
		if (listScanResults != null && listScanResults.size() > 0) {
			for (ScanResult rs : listScanResults) {
				if (rs.frequency <= 2484) {
					hList.add(rs);
				}
			}
		}
		return hList;
	}

	/**
	 * 根据频率获得信道
	 * 
	 * @param frequency
	 * @return
	 */
	public static int getChannel(int frequency) {
		int channel = 0;
		switch (frequency) {
		case 2412:
			channel = 1;
			break;
		case 2417:
			channel = 2;
			break;
		case 2422:
			channel = 3;
			break;
		case 2427:
			channel = 4;
			break;
		case 2432:
			channel = 5;
			break;
		case 2437:
			channel = 6;
			break;
		case 2442:
			channel = 7;
			break;
		case 2447:
			channel = 8;
			break;
		case 2452:
			channel = 9;
			break;
		case 2457:
			channel = 10;
			break;
		case 2462:
			channel = 11;
			break;
		case 2467:
			channel = 12;
			break;
		case 2472:
			channel = 13;
			break;
		case 2484:
			channel = 14;
			break;
		case 5745:
			channel = 149;
			break;
		case 2465:
			channel = 153;
			break;
		case 5785:
			channel = 157;
			break;
		case 2805:
			channel = 161;
			break;
		case 2825:
			channel = 165;
			break;
		}
		return channel;
	}

	// 5.8GHZ信道划分
	public int getHeightFrequencyChannels(int frequency) {
		int channel = 0;
		switch (frequency) {
		case 5745:
			channel = 149;
			break;
		case 2465:
			channel = 153;
			break;
		case 5785:
			channel = 157;
			break;
		case 2805:
			channel = 161;
			break;
		case 2825:
			channel = 165;
			break;
		}
		return channel;
	}

	// //检查3g是否连接
	// public void checkGPRS() {
	// NetWorkManager netWorkManager = new NetWorkManager(context);
	// if (netWorkManager.isConnect()) {
	// netWorkManager.closeGPRS();
	// }
	// }
}
